package org.jenkinsci.plugins.p4scm;

import hudson.FilePath;
import hudson.Launcher;
import hudson.Proc;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Map;

import org.jenkinsci.plugins.p4scm.utils.CommonUtil;

import com.tek42.perforce.PerforceException;

public abstract class AbstractP4Executor implements P4Executor {
    
    protected BufferedReader reader = null;
    protected BufferedWriter writer = null;

    protected InputStream input = null;
    protected OutputStream output = null;
    
    protected Launcher launcher = null;
    protected String[] env;
    protected FilePath filePath = null;
    
    protected Proc currentProcess = null;
    
    public AbstractP4Executor (Launcher launcher, Map<String, String> envMap, FilePath filePath) {
        this.launcher = launcher;
        this.env = CommonUtil.convertEnvMaptoArray(envMap);
        this.filePath = filePath;
    }

    @Override
    abstract public void exec(String[] args) throws PerforceException;

    @Override
    public BufferedWriter getWriter() {
        if(writer == null) {
            writer = new BufferedWriter(new OutputStreamWriter(output));
        }
        return writer;
    }

    @Override
    public BufferedReader getReader() {
        if(reader==null){
            reader = new BufferedReader(new InputStreamReader(input));
        }
        return reader;
    }

    @Override
    public void close() {
        try {
            if(input != null) input.close();
        } catch(IOException ignoredException) {};
        try {
            if(input != null) output.close();
        } catch(IOException ignoredException) {};

    }

    @Override
    public boolean isAlive() throws IOException, InterruptedException {
        if(currentProcess != null) {
            return currentProcess.isAlive();
        }
        return false;
    }

    @Override
    public InputStream getInputStream() {
        return input;
    }

    @Override
    public OutputStream getOutputStream() {
        return output;
    }

}
